package com.intelligent.system.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.intelligent.system.auth.entity.Person;
import com.intelligent.system.auth.mapper.PersonMapper;
import com.intelligent.system.auth.service.PersonService;
import com.intelligent.system.auth.dto.PersonDTO;
import com.intelligent.system.auth.dto.PersonQueryDTO;
import com.intelligent.system.common.exception.CustomException;
import com.intelligent.system.common.response.ResponseCode;
import com.intelligent.system.common.response.ResultDO;
import com.intelligent.system.common.utils.SnowflakeIdUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Objects;

@Slf4j
@Service
public class PersonServiceImpl extends ServiceImpl<PersonMapper, Person> implements PersonService {

    @Resource
    private PersonMapper personMapper;

    @Resource
    private SnowflakeIdUtils idUtils;

    @Override
    public ResultDO<IPage<PersonDTO>> page(PersonQueryDTO queryDTO) {
        try {
            log.info("分页查询人员列表, queryDTO: {}", queryDTO);
            Page<Person> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
            LambdaQueryWrapper<Person> wrapper = new LambdaQueryWrapper<>();

            // 添加查询条件
            if (StringUtils.hasText(queryDTO.getName())) {
                wrapper.like(Person::getName, queryDTO.getName());
            }
            if (StringUtils.hasText(queryDTO.getJob())) {
                wrapper.like(Person::getJob, queryDTO.getJob());
            }
            if (StringUtils.hasText(queryDTO.getGender())) {
                wrapper.eq(Person::getGender, queryDTO.getGender());
            }
            if (StringUtils.hasText(queryDTO.getContactMobile())) {
                wrapper.like(Person::getContactMobile, queryDTO.getContactMobile());
            }
            if (StringUtils.hasText(queryDTO.getPosition())) {
                wrapper.like(Person::getPosition, queryDTO.getPosition());
            }
            if (StringUtils.hasText(queryDTO.getRank())) {
                wrapper.eq(Person::getRank, queryDTO.getRank());
            }
            if (StringUtils.hasText(queryDTO.getIdCard())) {
                wrapper.eq(Person::getIdCard, queryDTO.getIdCard());
            }
            if (StringUtils.hasText(queryDTO.getStatus())) {
                wrapper.eq(Person::getStatus, queryDTO.getStatus());
            }
            if (queryDTO.getOrgId() != null) {
                wrapper.eq(Person::getOrgId, queryDTO.getOrgId());
            }

            // 添加排序条件
            wrapper.orderByDesc(Person::getUpdateTime);
            wrapper.eq(Person::getIsDelete, 0);

            IPage<Person> personPage = this.page(page, wrapper);
            return ResultDO.success(convertToDTOPage(personPage));
        } catch (Exception e) {
            log.error("分页查询人员列表异常, queryDTO: {}", queryDTO, e);
            throw new CustomException("分页查询人员列表失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDO<?> save(PersonDTO personDTO) {
        try {
            log.info("新增人员, personDTO: {}", personDTO);
            if (personDTO == null) {
                throw new CustomException("人员信息不能为空", ResponseCode.BAD_REQUEST.getCode());
            }

            // 检查手机号是否已存在
            if (StringUtils.hasText(personDTO.getContactMobile())) {
                Person existingPerson = this.getOne(new LambdaQueryWrapper<Person>()
                        .eq(Person::getContactMobile, personDTO.getContactMobile())
                        .eq(Person::getIsDelete, 0));
                if (existingPerson != null) {
                    throw new CustomException("手机号已存在", ResponseCode.OPERATION_FAILED.getCode());
                }
            }

            Person person = convertToEntity(personDTO);
            person.setId(idUtils.nextId());

            if (this.save(person)) {
                return ResultDO.success(null);
            }
            throw new CustomException("系统错误", ResponseCode.SYSTEM_ERROR.getCode());
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("新增人员异常, personDTO: {}", personDTO, e);
            throw new CustomException("新增人员失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDO<?> update(PersonDTO personDTO) {
        try {
            log.info("更新人员信息, personDTO: {}", personDTO);
            if (personDTO == null || personDTO.getId() == null) {
                throw new CustomException("人员信息或ID不能为空", ResponseCode.BAD_REQUEST.getCode());
            }

            // 检查人员是否存在
            Person existingPerson = this.getById(personDTO.getId());
            if (existingPerson == null) {
                throw new CustomException("人员不存在", ResponseCode.NOT_FOUND.getCode());
            }

            // 检查手机号是否已被其他人员使用
            if (StringUtils.hasText(personDTO.getContactMobile()) && 
                !personDTO.getContactMobile().equals(existingPerson.getContactMobile())) {
                Person personByMobile = this.getOne(new LambdaQueryWrapper<Person>()
                        .eq(Person::getContactMobile, personDTO.getContactMobile())
                        .eq(Person::getIsDelete, 0));
                if (personByMobile != null && !personByMobile.getId().equals(personDTO.getId())) {
                    throw new CustomException("手机号已被其他人员使用", ResponseCode.OPERATION_FAILED.getCode());
                }
            }

            Person person = convertToEntity(personDTO);
            person.setUpdateTime(LocalDateTime.now());

            if (this.updateById(person)) {
                return ResultDO.success(null);
            }
            throw new CustomException("系统错误", ResponseCode.SYSTEM_ERROR.getCode());
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新人员信息异常, personDTO: {}", personDTO, e);
            throw new CustomException("更新人员信息失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDO<?> removePersonById(Long id) {
        try {
            log.info("删除人员, id: {}", id);
            if (id == null) {
                throw new CustomException("人员ID不能为空", ResponseCode.BAD_REQUEST.getCode());
            }

            // 检查人员是否存在
            Person person = this.getById(id);
            if (person == null) {
                throw new CustomException("人员不存在", ResponseCode.NOT_FOUND.getCode());
            }

            // 逻辑删除
            person.setIsDelete(1);
            person.setUpdateTime(LocalDateTime.now());

            if (this.updateById(person)) {
                return ResultDO.success(null);
            }
            throw new CustomException("系统错误", ResponseCode.SYSTEM_ERROR.getCode());
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除人员异常, id: {}", id, e);
            throw new CustomException("删除人员失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    @Override
    public ResultDO<PersonDTO> getPersonById(Long id) {
        try {
            log.info("根据ID查询人员, id: {}", id);
            Person person = this.getById(id);
            if (person == null) {
                log.warn("人员不存在, id: {}", id);
                throw new CustomException("人员不存在", ResponseCode.NOT_FOUND.getCode());
            }
            return ResultDO.success(convertToDTO(person));
        } catch (CustomException e) {
            throw e;
        } catch (Exception e) {
            log.error("根据ID查询人员异常, id: {}", id, e);
            throw new CustomException("查询人员失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    private PersonDTO convertToDTO(Person person) {
        if (person == null) {
            return null;
        }
        try {
            PersonDTO dto = new PersonDTO();
            BeanUtils.copyProperties(person, dto);
            return dto;
        } catch (Exception e) {
            log.error("转换人员DTO异常, person: {}", person, e);
            throw new CustomException("转换人员信息失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    private IPage<PersonDTO> convertToDTOPage(IPage<Person> personPage) {
        if (personPage == null) {
            return null;
        }
        try {
            Page<PersonDTO> dtoPage = new Page<>();
            BeanUtils.copyProperties(personPage, dtoPage, "records");
            dtoPage.setRecords(personPage.getRecords().stream()
                    .map(this::convertToDTO)
                    .collect(java.util.stream.Collectors.toList()));
            return dtoPage;
        } catch (Exception e) {
            log.error("转换人员DTO分页异常, personPage: {}", personPage, e);
            throw new CustomException("转换人员分页信息失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }

    private Person convertToEntity(PersonDTO dto) {
        if (dto == null) {
            return null;
        }
        try {
            Person person = new Person();
            BeanUtils.copyProperties(dto, person);
            return person;
        } catch (Exception e) {
            log.error("转换人员实体异常, dto: {}", dto, e);
            throw new CustomException("转换人员信息失败", ResponseCode.SYSTEM_ERROR.getCode(), e);
        }
    }
} 